﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;

namespace LigerMVC.Common.JSON
{
    public class JSONSerializerFactory
    {
        private readonly IDictionary<RuntimeTypeHandle, Func<IJSONSerializer>> regFactories;

        private readonly IDictionary<RuntimeTypeHandle, Func<IJSONSerializer>> factories;

        public JSONSerializerFactory()
        {
            regFactories = new Dictionary<RuntimeTypeHandle, Func<IJSONSerializer>>();
            factories = GetDefaultFactories();
        }


        #region 注册外部工厂
        public JSONSerializerFactory Register<TService>(object serializer)
        {
            return Register<TService>(() => serializer as IJSONSerializer);
        }

        public JSONSerializerFactory Register<TService>(Func<IJSONSerializer> func)
        {
            var typeHandle = typeof(TService).TypeHandle;
            Func<IJSONSerializer> serializerFac = null;
            if (!regFactories.TryGetValue(typeHandle, out serializerFac))
            {
                if (serializerFac == null)
                {
                    regFactories[typeHandle] = func;
                } 
            } 
            return this;
        }
        #endregion

        #region 默认工厂
        private IDictionary<RuntimeTypeHandle, Func<IJSONSerializer>> GetDefaultFactories()
        {
            return new Dictionary<RuntimeTypeHandle, Func<IJSONSerializer>>()
            {
                  { typeof(DataSet).TypeHandle, () => new DataSetJSONSerializer() },
                  { typeof(DataTable).TypeHandle, () => new DataSetJSONSerializer() },
                  { typeof(ArrayList).TypeHandle, () => new MsJSONSerializer() },
                  { typeof(Array).TypeHandle, () => new MsJSONSerializer() }, 
                  { typeof(Hashtable).TypeHandle, () => new MsJSONSerializer() }
            };
        }
        #endregion



        public IJSONSerializer Create(RuntimeTypeHandle typeHandle)
        {
            Func<IJSONSerializer> serializerFac = null;

            regFactories.TryGetValue(typeHandle, out serializerFac);

            if (serializerFac == null)
                factories.TryGetValue(typeHandle, out serializerFac);

            if (serializerFac == null) return new MsJSONSerializer();
            var serializer = serializerFac();
            if (serializer == null) return new MsJSONSerializer();
            return serializer;
        }
    }
}
